//
//  MYKRequestManager.m
//  ZFGT
//
//  Created by apple on 2017/12/19.
//  Copyright © 2017年 allyoubank.com. All rights reserved.
//

#import "MYKRequestManager.h"
#import <AFNetworking.h>
#import "MYKHttpsSecurityVerification.h"
#import <YYModel.h>
//#import "SBLLocalUserManager.h"
#import "NSString+MD5.h"

//验签参数
#define AppKey @"BCFFE4852D42A12318C907B20A491EA6"
#define AppSecret @"BCFFE4852D42A12318C907B20A491EA6"

/** 字符串是否为空 */
#define MYK_StringIsEmpty(str) ([str isKindOfClass:[NSNull class]] || [str isEqualToString:@"<null>"] || [str isEqualToString:@"(null)"]|| str == nil || [str length] < 1 ? YES :NO)

/** 数组是否为空  */
#define MYK_ArrayIsEmpty(array) (array == nil || [array isKindOfClass:[NSNull class]] || array.count == 0)

/** 字典是否为空  */
#define MYK_DictIsEmpty(dic) (dic == nil || [dic isKindOfClass:[NSNull class]] || dic.count == 0)


/// 设置请求超时时间
static const NSTimeInterval MYK_requestTimeoutInterval = 15;
static MYKRequestManager *_manager = nil;


@interface MYKRequestManager()

// 是否隐藏HUD
@property (nonatomic, assign) BOOL tostHideWhenFinish;

/**
 公共参数
 */
@property (nonatomic, strong) NSDictionary *bodyArguments;

@end

@implementation MYKRequestManager

+ (instancetype)sharedManager
{
    static dispatch_once_t oncePredicate;
    dispatch_once(&oncePredicate, ^{
        _manager = [MYKRequestManager manager];
        _manager.responseSerializer = [AFJSONResponseSerializer serializer];
        _manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json",@"text/json", @"text/javascript",@"text/html",@"text/plain",nil];
    });
    
    return _manager;
}

+ (MYKRequestManager *)configManager:(NSTimeInterval)timeoutInterval param:(NSDictionary *)param{
    _manager = [MYKRequestManager manager];
    _manager.responseSerializer = [AFJSONResponseSerializer serializer];
    _manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json",@"text/json", @"text/javascript",@"text/html",@"text/plain",nil];
    _manager.requestSerializer.timeoutInterval = timeoutInterval;
    
//    [MYKRequestManager myk_httpsSecurityVerificationWithAFManager:manager];  //https 双向验证
    
    //用户信息 Header
    _manager.bodyArguments = param;
    NSMutableDictionary *headerArguments = [NSMutableDictionary dictionaryWithCapacity:2];
//    if ([SBLLocalUserManager userIsLogin]) {
//        SBLUserModel *user = [SBLLocalUserManager getUser];
//        [headerArguments setObject:user.token forKey:@"token"];
//    }
//    else {
//        [headerArguments setObject:@"" forKey:@"token"];
//    }
//    [headerArguments setObject:[_manager returnSignature] forKey:@"signMsg"];
    for (NSString *key in headerArguments) {
        [_manager.requestSerializer setValue:headerArguments[key] forHTTPHeaderField:key];
    }
    
    
    return _manager;
}
//
//- (NSString *)returnSignature {
//    NSMutableString *mutabelString = [[NSMutableString alloc] initWithString:[NSString stringWithFormat:@"%@",AppKey]];
//    if ([SBLLocalUserManager userIsLogin]) {
//        [mutabelString appendString:[SBLLocalUserManager getUser].token];
//    }
//    //排序
//    NSArray *sortKey = [self.bodyArguments.allKeys sortedArrayUsingSelector:@selector(compare:)];
//    //body 字段拼接
//    NSString *paramsStr = [self returnSignature:sortKey arguments:self.bodyArguments] ;
//    //body 字段和appkey + token 拼接
//    [mutabelString appendString:[NSString stringWithFormat:@"%@",paramsStr]];
//    //MD5 结果
//    mutabelString = [[NSString md5WithString:mutabelString] mutableCopy];
//    //uppercaseString 转大写
//    return [mutabelString uppercaseString];
//}

- (NSString *)returnSignature:(NSArray *)keySort arguments:(NSDictionary *)arguments
{
    NSMutableString *mutabelString = [[NSMutableString alloc] init];
    for (NSString *key in keySort) {
        [mutabelString appendFormat:@"%@=%@",key,arguments[key]];
        [mutabelString appendString:@"|"];
    }
    //过滤最后一个|符号
    NSString *temStr = @"";
    if (mutabelString.length) {
        temStr = [mutabelString substringToIndex:mutabelString.length-1];
    }
    return temStr;
}


+ (void)setToastHidden:(BOOL)hidden {
    _manager.tostHideWhenFinish = hidden;
}


//MARK: - post 请求数据
+ (void)postRequestWithURL:(NSString *)url
                    params:(NSDictionary *)params
            successRequest:(MYKSuccessRequest)success
                 dataError:(MYKDataErrorRequest)dataError
               failRequest:(MYKFailureRequest)fail
{
    [MYKRequestManager postRequestWithURL:url params:params timeoutInterval:MYK_requestTimeoutInterval successRequest:success dataError:dataError failRequest:fail];
}

+ (void)postRequestWithURL:(NSString *)url
                    params:(NSDictionary *)params
           timeoutInterval:(NSTimeInterval)timeoutInterval
            successRequest:(MYKSuccessRequest)success
                 dataError:(MYKDataErrorRequest)dataError
               failRequest:(MYKFailureRequest)fail
{
    NSString *urlStr = [NSString stringWithFormat:@"%@",url];
    //拼接公共参数
    NSDictionary *temParams = [MYKRequestManager appendPublicParamWithNormalParam:params];
    
    MYKRequestManager *manager = [self configManager:timeoutInterval param:temParams];

    [manager POST:urlStr parameters:temParams progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        [MYKRequestManager handleRequestSuccessWithResponse:responseObject entityClass:nil arrayEntity:nil Success:success dataError:dataError];
        
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        [MYKRequestManager handleRequestFailedWithError:error fail:fail];
    }];
}


/**
 post 请求 解析data内部数据解析成一个对象
 
 *  @params url 接口字段
 *  @params params 请求参数(NSDictionary 形式)
 *  @param entityClass 要返回的类（如 [UserEntity class] / [NSString class]）
 *  @params success 请求成功 -- 业务成功回调
 *  @params dataError 请求成功 -- 业务失败回调
 *  @params fail 请求失败回调
 */
+ (void)postEntiyWithSubPath:(NSString *)url
                      params:(NSDictionary *)params
                 entityClass:(Class)entityClass
              successRequest:(MYKSuccessRequest)success
                   dataError:(MYKDataErrorRequest)dataError
                 failRequest:(MYKFailureRequest)fail {

    NSString *urlStr = [NSString stringWithFormat:@"%@",url];
    //拼接公共参数
    NSDictionary *temParams = [MYKRequestManager appendPublicParamWithNormalParam:params];
    
    MYKRequestManager *manager = [self configManager:MYK_requestTimeoutInterval param:temParams];

    [manager POST:urlStr parameters:temParams progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        [MYKRequestManager handleRequestSuccessWithResponse:responseObject entityClass:entityClass arrayEntity:nil Success:success dataError:dataError];

    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        [MYKRequestManager handleRequestFailedWithError:error fail:fail];
    }];
}

+ (void)postArrayWithSubPath:(NSString *)url
                      params:(NSDictionary *)params
                 entityClass:(Class)entityClass
              successRequest:(MYKSuccessRequest)success
                   dataError:(MYKDataErrorRequest)dataError
                 failRequest:(MYKFailureRequest)fail {

    NSString *urlStr = [NSString stringWithFormat:@"%@",url];
    //拼接公共参数
    NSDictionary *temParams = [MYKRequestManager appendPublicParamWithNormalParam:params];
    
    MYKRequestManager *manager = [self configManager:MYK_requestTimeoutInterval param:temParams];

    [manager POST:urlStr parameters:temParams progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        [MYKRequestManager handleRequestSuccessWithResponse:responseObject entityClass:nil arrayEntity:entityClass Success:success dataError:dataError];
        
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        [MYKRequestManager handleRequestFailedWithError:error fail:fail];
    }];
}


//MARK: - get 请求
+ (void)getRequestWithURL:(NSString *)url
                   params:(NSDictionary *)params
          timeoutInterval:(NSTimeInterval)timeoutInterval
           successRequest:(MYKSuccessRequest)success
                dataError:(MYKDataErrorRequest)dataError
              failRequest:(MYKFailureRequest)fail
{

    NSString *urlStr = [NSString stringWithFormat:@"%@",url];
    //拼接公共参数
    NSDictionary *temParams = [MYKRequestManager appendPublicParamWithNormalParam:params];
    
    MYKRequestManager *manager = [self configManager:timeoutInterval param:temParams];

    
    [manager GET:urlStr parameters:temParams progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        [self handleRequestSuccessWithResponse:responseObject entityClass:nil arrayEntity:nil Success:success dataError:dataError];;
        
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        [self handleRequestFailedWithError:error fail:fail];
    }];
}

+ (void)getArrayRequestWithURL:(NSString *)url
                        params:(NSDictionary *)params
                   entityClass:(Class)entityClass
                successRequest:(MYKSuccessRequest)success
                     dataError:(MYKDataErrorRequest)dataError
                   failRequest:(MYKFailureRequest)fail {

    [MYKRequestManager getArrayRequestWithURL:url params:params entityClass:entityClass timeoutInterval:MYK_requestTimeoutInterval successRequest:success dataError:dataError failRequest:fail];
}

+ (void)getArrayRequestWithURL:(NSString *)url
                        params:(NSDictionary *)params
                   entityClass:(Class)entityClass
               timeoutInterval:(NSTimeInterval)timeoutInterval
                successRequest:(MYKSuccessRequest)success
                     dataError:(MYKDataErrorRequest)dataError
                   failRequest:(MYKFailureRequest)fail {
    
    NSString *urlStr = [NSString stringWithFormat:@"%@",url];
    //拼接公共参数
    NSDictionary *temParams = [MYKRequestManager appendPublicParamWithNormalParam:params];
    
    MYKRequestManager *manager = [self configManager:timeoutInterval param:temParams];

    [manager GET:urlStr parameters:temParams progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        [self handleRequestSuccessWithResponse:responseObject entityClass:nil arrayEntity:entityClass Success:success dataError:dataError];;
        
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        [self handleRequestFailedWithError:error fail:fail];
    }];
}


+ (void)getEntiyWithSubPath:(NSString *)url
                     params:(NSDictionary *)params
                entityClass:(Class)entityClass
             successRequest:(MYKSuccessRequest)success
                  dataError:(MYKDataErrorRequest)dataError
                failRequest:(MYKFailureRequest)fail {
    NSString *urlStr = [NSString stringWithFormat:@"%@",url];
    //拼接公共参数
    NSDictionary *temParams = [MYKRequestManager appendPublicParamWithNormalParam:params];
    
    MYKRequestManager *manager = [self configManager:MYK_requestTimeoutInterval param:temParams];

    [manager GET:urlStr parameters:temParams progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        [self handleRequestSuccessWithResponse:responseObject entityClass:entityClass arrayEntity:nil Success:success dataError:dataError];;
        
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        [self handleRequestFailedWithError:error fail:fail];
    }];
}


//MARK: - 公共参数
+ (NSDictionary *)appendPublicParamWithNormalParam:(NSDictionary *)params
{
    NSMutableDictionary *temParams = [NSMutableDictionary dictionary];
    if (params == nil || ![params isKindOfClass:[NSDictionary class]]) {
        temParams = [NSMutableDictionary new];
    } else {
        temParams = [params mutableCopy];
    }
    
    /// - 公共参数
    //1是代表iOS
    [temParams setObject:@"1" forKey:@"mobileType"];
    
    //版本号
    NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary];
    [temParams setObject:[infoDictionary objectForKey:@"CFBundleShortVersionString"] forKey:@"versionNumber"];
    
    //用户信息
//    if ([SBLLocalUserManager userIsLogin]) {
//        SBLUserModel *user = [SBLLocalUserManager getUser];
//        [temParams setObject:user.userId forKey:@"userId"];
//        [temParams setObject:user.token forKey:@"token"];
//    }
    
    return [temParams copy];
}

//MARK: - Https证书配置
+ (void)myk_httpsSecurityVerificationWithAFManager:(MYKRequestManager *)manager
{
//    [MYKHttpsSecurityVerification myk_httpsSecurityVerificationWithAFManager:manager];
}


#pragma mark - 请求结果处理

// 解析成字典
+ (void)handleRequestSuccessWithResponse:(id)response
                             entityClass:(Class)entityClass
                             arrayEntity:(Class)arrayEntity
                          Success:(MYKSuccessRequest)success
                   dataError:(MYKDataErrorRequest)dataError {
    NSLog(@"%@", response);
    [MYKRequestManager setToastHidden:NO];

    //
    if ([response isKindOfClass:[NSDictionary class]]) {
        MYKRequestModel *requestModel = [[MYKRequestModel alloc] initWithDictionary:response];
        if (requestModel.code.integerValue == 200) {

            if (!_manager.tostHideWhenFinish) {
             //   [SVProgressHUD dismiss];
            }
            
            if (success != nil) {
                // 如果需要将data解析成一个对象
                if (entityClass) {
                    if (requestModel && [requestModel.data isKindOfClass:[NSDictionary class]]) {
                        id entity = [entityClass yy_modelWithDictionary:requestModel.data];
                        requestModel.dataEntity = entity;
                        success(requestModel);
                    }
                    else {
                        success(requestModel);
                    }
                }
                // 如果需要将data解析成一个数组，并且包含对象
                else if (arrayEntity) {
                    if (requestModel && [requestModel.data isKindOfClass:[NSArray class]]) {
                        NSMutableArray *dataArray = [NSMutableArray array];
                        for (id obj in requestModel.data) {
                            if ([obj isKindOfClass:[NSDictionary class]]) {
                                id entity = [arrayEntity yy_modelWithDictionary:obj];
                                [dataArray addObject:entity];
                            }
                        }
                        requestModel.dataArray = dataArray;
                        success(requestModel);
                    }
                    else {
                        if (dataError != nil) {
                            dataError(requestModel);
                        }
                        
                        if (!_manager.tostHideWhenFinish) {
                            // 先取data 再去取msg
                            if (requestModel.data && [requestModel.data isKindOfClass:NSString.class] && !MYK_StringIsEmpty(requestModel.data)) {
                              //  [SVProgressHUD showWarningWithTitle:requestModel.data];
                            }
                            else {
                                if (requestModel.msg && requestModel.msg.length > 0) {
                                 //   [SVProgressHUD showWarningWithTitle:requestModel.msg];
                                }
                                else {
                                  //  [SVProgressHUD showWarningWithTitle:@"网络数据异常,请重新获取"];
                                }
                            }
                        }
                    }
                }
                else {
                    success(requestModel);
                }
            }
        } else {
            //接口报410就是挤下去了
            if (requestModel.code) {
                if ([requestModel.code integerValue] == 410) {
                    /// 登录被挤，发出通知
                    [[NSNotificationCenter defaultCenter] postNotificationName:@"Notification_UserShouldLogOut" object:nil];
                }
            }
            
            if (dataError != nil) {
                dataError(requestModel);
            }
            
            if (!_manager.tostHideWhenFinish) {
                // 先取data 再去取msg
                if (requestModel.data && [requestModel.data isKindOfClass:NSString.class] && !MYK_StringIsEmpty(requestModel.data)) {
                   // [SVProgressHUD showWarningWithTitle:requestModel.data];
                }
                else {
                    if (requestModel.msg && requestModel.msg.length > 0) {
                       // [SVProgressHUD showWarningWithTitle:requestModel.msg];
//                        [MBProgressHUD showError:requestModel.msg];
                    }
                    else {
                       // [SVProgressHUD showWarningWithTitle:@"网络数据异常,请重新获取"];
                    }
                }
            }
            else {
              //  [SVProgressHUD dismiss];
            }
        }
        
    } else {
        MYKRequestModel *requestModel = [[MYKRequestModel alloc] init];
        requestModel.msg = @"网络数据异常,请重新获取";

        if (dataError != nil) {
            dataError(requestModel);
        }
        
        if (!_manager.tostHideWhenFinish) {
           // [SVProgressHUD showWarningWithTitle:requestModel.msg];
        }
        else {
          //  [SVProgressHUD dismiss];
        }
    }
}


+ (void)handleRequestFailedWithError:(NSError *)error
                                fail:(MYKFailureRequest)fail {
    [MYKRequestManager setToastHidden:NO];
    if (error) {
        fail(error);
    }
    if (!_manager.tostHideWhenFinish) {
      //  [SVProgressHUD showWarningWithTitle:@"网络异常"];
    }
    else {
      //  [SVProgressHUD hideHUD];
    }
}

@end
